home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Online / Socks5 / src / server / sident.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-10  |  4.8 KB  |  182 lines

  1. /* Copyright (c) 1995-1999 NEC USA, Inc.  All rights reserved.               */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6.  
  7. /*
  8.  * $Id: sident.c,v 1.19.2.1.2.1 1999/02/03 22:35:44 steve Exp $
  9.  */
  10.  
  11. #include "socks5p.h"
  12. #include "threads.h"
  13. #include "daemon.h"
  14. #include "addr.h"
  15. #include "log.h"
  16.  
  17. #ifdef HAVE_LIBIDENT
  18. #include <ident.h>
  19. #endif
  20.  
  21. #ifndef IDENTTIMEOUT
  22. #define IDENTTIMEOUT 15
  23. #endif
  24.  
  25. #ifdef HAVE_LIBIDENT
  26. static inline void filelock(S5IOHandle fd, int on) {
  27. #if defined(HAVE_FLOCK) && !defined(F_SETLKW)
  28.     flock(fd, on?LOCK_EX:LOCK_UN);
  29. #else
  30.     struct flock fl;
  31.     
  32.     fl.l_type   = on?F_WRLCK:F_UNLCK;
  33.     fl.l_whence = SEEK_SET;
  34.     fl.l_start  = 0;
  35.     fl.l_len    = 0;
  36.  
  37.     fcntl(fd, F_SETLKW, &fl);
  38. #endif
  39. }
  40.  
  41. static inline S5IOHandle openidtfile(void) {
  42.     int flags = O_RDWR | O_CREAT;
  43.     S5IOHandle fd;
  44.     struct stat sbuf;
  45.     static char *myfile = NULL;
  46.     
  47.     if (!myfile) {
  48.         MUTEX_LOCK(env_mutex);
  49.         myfile = getenv("SOCKS5_IDENTFILE");
  50.         myfile = myfile?strdup(myfile):strdup(SRVIDT_FILE);
  51.     }
  52.  
  53.     if (lstat(myfile, &sbuf) || (S_ISLNK(sbuf.st_mode) && geteuid() != sbuf.st_uid)) flags |= O_EXCL;
  54.     fd = open(myfile, flags, 0644);
  55.     MUTEX_UNLOCK(env_mutex);
  56.  
  57.     if (fd == S5InvalidIOHandle) return fd;
  58.     filelock(fd, 1);
  59.     return fd;
  60. }
  61. #endif
  62.  
  63. int IdentQuery(S5IOHandle fd, char *name) {
  64. #ifndef HAVE_LIBIDENT
  65.     return 0;
  66. #else
  67.     IDENT *idp;
  68.     char *ev;
  69.     int rval;
  70.  
  71.     IFTHREADED(static MUTEX_T idt_mutex = MUTEX_INITIALIZER;)
  72.  
  73.     IFTHREADED(MUTEX_SETUP(idt_mutex);)
  74.  
  75.     MUTEX_LOCK(env_mutex);
  76.     ev = getenv("SOCKS5_NOIDENT");
  77.     MUTEX_UNLOCK(env_mutex);
  78.     
  79.     if (ev) {
  80.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: No Ident lookup (by request)");
  81.     *name = '\0';
  82.     return -1;
  83.     } 
  84.  
  85.     MUTEX_LOCK(idt_mutex);
  86.  
  87.     if ((idp = ident_lookup(fd, IDENTTIMEOUT)) == NULL) {
  88.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident lookup failed: %m");
  89.     *name = '\0';
  90.     rval = -1;
  91.     } else {
  92.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident lookup name was: %s", idp->identifier);
  93.     strncpy(name, idp->identifier, MIN(strlen(idp->identifier)+1, S5_USERNAME_SIZE));
  94.     if (strlen(idp->identifier)+1 > S5_USERNAME_SIZE) name[S5_USERNAME_SIZE-1] = '\0';
  95.     ident_free(idp);
  96.     rval = 0;
  97.     }
  98.     
  99.     MUTEX_UNLOCK(idt_mutex);
  100.     return rval;
  101. #endif
  102. }
  103.     
  104. void InitIdentEntry(char *idtentry) {
  105.     idtentry[0] = '\0';
  106. }
  107.  
  108. void RemoveIdentEntry(char *idtentry) {
  109. #ifdef HAVE_LIBIDENT
  110.     char *fbuf = NULL, *offset;
  111.     struct stat sb;
  112.     S5IOHandle fd;
  113.  
  114.     if (*idtentry == '\0') return;
  115.     if ((fd = openidtfile()) == S5InvalidIOHandle) return;
  116.  
  117.     if (fstat(fd, &sb) < 0) goto end;
  118.     if (!(fbuf = (char *)malloc((sb.st_size+1)*sizeof(char)))) goto end;
  119.     if (READFILE(fd, fbuf, sb.st_size) < 0) goto end;
  120.     fbuf[sb.st_size] = '\0';
  121.     
  122.     if ((offset = strstr(fbuf, idtentry)) == NULL) goto end;
  123.     lseek(fd, offset-fbuf, 0);
  124.     WRITEFILE(fd, offset + strlen(idtentry), (sb.st_size - (offset-fbuf) - strlen(idtentry)));
  125.  
  126.     /* XXX For now, if you don't have ftruncated, you loose.  BSD & SVR4 */
  127.     /* both do, so there shouldn't be too many losers.                   */
  128.     ftruncate(fd, sb.st_size - strlen(idtentry));
  129.     
  130.   end:
  131.     if (fbuf) free(fbuf);
  132.     if (fd >= 0) close(fd);
  133. #endif
  134. }
  135.  
  136. void MakeIdentEntry(S5IOHandle in, S5IOHandle out, S5LinkInfo *linkinfo, char *idtentry) {
  137. #ifdef HAVE_LIBIDENT
  138.     char *user, identname[S5_USERNAME_SIZE];
  139.     S5NetAddr tmp, *dst;
  140.     S5IOHandle fd;
  141.     int len;
  142.  
  143.     if (*idtentry != '\0') {
  144.     RemoveIdentEntry(idtentry);
  145.     }
  146.  
  147.     if (linkinfo->peerAuth == AUTH_NONE || IdentQuery(in, identname) < 0) {
  148.     user = linkinfo->srcUser;
  149.     } else {
  150.     user = identname;
  151.     }
  152.  
  153.     if (!strlen(user)) {
  154.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Not recording ident info for empty username");
  155.     return;
  156.     }
  157.  
  158.     if (linkinfo->nextVersion) {
  159.     dst = &linkinfo->sckAddr;
  160.     } else {
  161.     dst = &linkinfo->dstAddr;
  162.     }
  163.  
  164.     len = sizeof(S5NetAddr);
  165.     memset(&tmp, 0, len);
  166.     getsockname(out, &tmp.sa, &len);
  167.  
  168.     sprintf(idtentry, "%s,%d,", ADDRANDPORT(dst));
  169.     sprintf(idtentry+strlen(idtentry), "%s,%d,", ADDRANDPORT(&tmp));
  170.     sprintf(idtentry+strlen(idtentry), "%s\n",   user);
  171.  
  172.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Recording ident info for user: %s", user);
  173.  
  174.     if ((fd = openidtfile()) == S5InvalidIOHandle) return;
  175.     WRITEFILE(fd, idtentry, strlen(idtentry));
  176.     close(fd);
  177.  
  178.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident info recorded");
  179. #endif
  180. }
  181.  
  182.